#include "lightcontrol.h"
#include <QProcess>
#include <QDebug>
#include "playvoice.h"
#include "mylogger.h"

using namespace ns_yht;
LightControl::LightControl()
{
    for (int i = 0; i < 3; i++)
    {
        m_lightStates[i] = LightState(-1, false);
        m_newStates[i] = -1;
    }
}

LightControl::~LightControl()
{
    if (m_timer)
        delete m_timer;
    if (m_process)
    {
        m_process->deleteLater();
        m_process = nullptr;
    }
    if (m_processMute)
    {
        m_processMute->deleteLater();
        m_processMute = nullptr;
    }
}

void LightControl::turnOn(int lightId, bool on)
{
    m_newStates[lightId] = on ? 1 : 0;
}

void LightControl::startShrink(int lightId)
{
    m_lightStates[lightId].second = true;
}

void LightControl::stopShrink(int lightId)
{
    m_lightStates[lightId].second = false;
}

void LightControl::processCommand(int lightId, int command)
{
    static const QMap<int, int> lightIdToControlId = {
        {LightColor::Red, 0},
        {LightColor::Green, 3},
        {LightColor::Blue, 1}};

    int controlId = lightIdToControlId[lightId];
#if defined(Q_OS_LINUX)
    if (m_process == nullptr)
    {
        m_process = new QProcess(this);
        connect(m_process, &QProcess::errorOccurred, this, &LightControl::onProcessError);
    }
    m_process->start("gpioset", {"gpiochip2", QString("%1=%2").arg(controlId).arg(command)});
    m_process->waitForFinished(300);
#endif
#if defined(Q_OS_WIN)

#endif
}

void LightControl::start()
{
    m_timer = new QTimer;
    connect(m_timer, &QTimer::timeout, this, &LightControl::onTimer);
    m_timer->start(300);
}

void LightControl::onTimer()
{
    for (int i = 0; i < 3; i++)
    {
        if (m_lightStates[i].second)
        {
            m_lightStates[i].first = !m_lightStates[i].first;
            processCommand(i, m_lightStates[i].first);
        }
        else if (m_newStates[i] != m_lightStates[i].first)
        {
            m_lightStates[i].first = m_newStates[i];
            processCommand(i, m_lightStates[i].first);
        }
    }
    // detectMute(); //改为main中gpioinput实现
}

void LightControl::detectMute()
{
#if defined(Q_OS_LINUX)
    if (!m_processMute)
    {
        m_processMute = new QProcess(this);
        connect(m_processMute, &QProcess::errorOccurred, this, &LightControl::onProcessMuteError);
    }
    m_processMute->start("gpioget", {"gpiochip2", "4"});
    m_processMute->waitForFinished(300);

    QString output = m_processMute->readAllStandardOutput().trimmed();

    bool ok;
    int mute = output.toInt(&ok);
    if (!ok)
    {
        qWarning() << "Failed to parse mute status:" << output;
        return;
    }
    if (mute == 0)
    {
        GLOG->debug("detectMute:0");
        emit ensureCurrent();
    }

#endif
}

void LightControl::onProcessError(QProcess::ProcessError error)
{
    GLOG->info("light control process error {}", int(error));
}

void LightControl::onProcessMuteError(QProcess::ProcessError error)
{
    GLOG->info("light control process mute error {}", int(error));
}

//====================================================LightTask====================================================

LightTask::LightTask(QObject *parent)
    : QObject(parent)
{
    m_lightControl = new LightControl;
    connect(this, &LightTask::signalOfStartShrink, m_lightControl, &LightControl::startShrink);
    connect(this, &LightTask::signalOfStopShrink, m_lightControl, &LightControl::stopShrink);
    connect(this, &LightTask::signalOfTurnOn, m_lightControl, &LightControl::turnOn);
    connect(this, &LightTask::signalOfStart, m_lightControl, &LightControl::start);
    // connect(m_lightControl, &LightControl::ensureCurrent, PLAYVOICE, &PlayVoice::ensureCurrentMsgModel);

    m_lightControl->moveToThread(&m_thread);
    m_thread.start();
}

LightTask::~LightTask()
{
    m_thread.quit();
    m_thread.wait();
    delete m_lightControl;
}

LightTask *LightTask::instance()
{
    static LightTask lightTask;
    return &lightTask;
}

void LightTask::start()
{
    emit signalOfStart();
}

void LightTask::startShrink(int lightId)
{
    emit signalOfStartShrink(lightId);
}

void LightTask::stopShrink(int lightId)
{
    emit signalOfStopShrink(lightId);
}

void LightTask::turnOn(int lightId, bool on)
{
    emit signalOfTurnOn(lightId, on);
}
